package dao.hibernate;

import dao.common.BrandManager;
import models.entities.PaginatedList;
import models.shop.Brand;
import models.shop.Category;
import models.shop.Image;
import models.shop.path.ProductFilter;

import java.util.List;

public class BrandManagerHB implements BrandManager {
    public Brand create(String title, Image image) {
        Brand brand = new Brand(title, image);
        save(brand);
        return brand;
    }
    public void save(Brand brand) {
        brand.save();
    }
    public List<Brand> listTopBrands(int count) {
        List<Brand> results = Brand.find("select " +
                "new Brand(p.brand.id, " +
                "           p.brand.title, " +
                "           count(p.brand.id) as productsCount, " +
                "           p.brand.images.size)" +
                "from Product p " +
                "where p.archived = false " +
                "group by p.brand.id order by productsCount desc").fetch(count);
        return results;
    }

    public PaginatedList<Brand> paginatedList(ProductFilter filter){
        List<Brand> brands = list(filter);
        Category category = Category.findById(filter.categoryId);
        String countQuery = "select count(distinct b) from Brand b, Product p where b.id = p.brand.id and p.category.leftValue >= ? and p.category.rightValue <= ?";
        long totalCount = Brand.count(countQuery, category.leftValue, category.rightValue);
        PaginatedList<Brand> paginatedList = new PaginatedList<Brand>(brands, totalCount, 5);
        return paginatedList;
    }
    public List<Brand> list(ProductFilter filter) {
        Category category = Category.findById(filter.categoryId);
        String brandQuery = "Select new Brand(p.brand.id, " +
                "               p.brand.title, " +
                "               count(p.brand.id) as productsCount, " +
                "               p.brand.images.size) " +
                "from Product p, " +
                "Category c where p.category.id = c.id and" +
                " p.archived = false and " +
                "c.leftValue >= ? and c.rightValue <= ? " +
                "group by p.brand.id order by productsCount desc";
        List<Brand> brands = Brand.find(brandQuery, category.leftValue, category.rightValue).fetch(filter.brandPage, 5);
        return brands;
    }

    public Brand getById(int brandId) {
        return Brand.find("select " +
                "new Brand(brand.id, " +
                "           brand.title, " +
                "           0, " +
                "           brand.images.size)" +
                "from Brand brand where brand.id = ?", brandId).first();
    }

    public PaginatedList<Brand> listAll(int pageNumber, int pageSize) {
        List<Brand> brands = Brand.find("select new Brand(b.id, b.title, 0, b.images.size) from Brand b").fetch(pageNumber, pageSize);
        long brandsCount = Brand.count();
        PaginatedList<Brand> result = new PaginatedList<Brand>(brands, brandsCount, pageSize);
        return result;
    }

    public void updateImage(int brandId, Image image) {
        Brand brand = Brand.findById(brandId);
        brand.images.clear();
        image.save();
        brand.images.add(image);
        brand.save();
    }

    public void deleteImage(int brandId, String md5) {
        Brand brand = Brand.findById(brandId);
        for (Image image : brand.images){
            if (image.md5.equals(md5)){
                image.delete();
            }
        }
        brand.save();
        Image.delete("byMd5", md5);
    }

    public Image getExistentImage(int brandId) {
        Brand brand = Brand.findById(brandId);
        if (brand.images.size() > 0){
            return brand.images.get(0);
        }
        return null;
    }
}
